home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
JCSM Shareware Collection 1993 November
/
JCSM Shareware Collection - 1993-11.iso
/
cl720
/
vxbase1j.lzh
/
README.TXT
< prev
next >
Wrap
Text File
|
1993-06-18
|
58KB
|
1,573 lines
vxBase 3.02 June 18, 993
-------------------------
This is a new major release of vxBase numbered 3.0X. It contains a new set of
functions designed to store, manage, and retrieve bitmaps. It also contains
a set of functions that will create and maintain permanent subindexes - plus
MORE. In all, 18 new functions have been added.
Changes to version vxBase 2.xx are documented after the new function
writeups.
NOTE: Release 3.02 adds function vxLockRetry which allows much greater
flexibility in locking protocol and error reporting. See below.
BITMAPS
-------
The bitmaps are stored in standard xBase memo files. Fields in the dbf which
contain block references to the bitmaps are standard type "M" fields. An
attempt to display the bitmap using third party xBase software (e.g., Clipper
or even the current release of DataWorks) will show "BIT*MAP". If these
memos are replaced with text, the bitmaps will be lost.
An updated vxbtest project is included in the zip. To show off the bitmap
functions, run it and select "Link" and then "Show Pictures" from the
main menu. The code that shows the bitmaps is in VYFORM2. If you are running
the sample on a low resolution monitor (i.e., 640x480), maximize
the form. You should also make the vxCtlBrowse box a little wider and
deeper.
Collecting Bitmaps
------------------
Images stored in a vxBase memo file are most easily transferred via
a bitmap file (files with .BMP extensions).
vxBase takes advantage of the rich body of functions included in Visual
Basic to handle bitmap files. Bitmaps are the Windows norm; all paint
programs, viewers, etc. can handle bitmaps - and most programs that
deal with pictures can convert foreign formats (e.g., GIF) to BMPs.
As a last resort, cut a picture into the clipboard and paste it into a
Windows PAINT window. It can then be stored as a .BMP file.
Once an image is stored in a BMP file it can be transferred to the
memo file with the vxPictureImport function. To retrieve the bitmap,
vxBase uses the standard Windows Clipboard. It puts the bitmap out to
the clipboard as a DIB (device independent bitmap). The Visual Basic
Clipboard.GetData(8) function then is used to retrieve the image
from the clipboard and display it in a VB Picture Box. The box
can have the AUTORESIZE property set to TRUE as in the sample
application if the images are all different sizes
C programmers can store ANY KIND of BLOB (binary large object) in a memo
file with vxBlobWrite and retrieve the BLOBs with vxBlobRead. Contact the
author for more information on these functions.
SUBINDEXES
----------
A subindex is an index that represents a defined subset of records in the
main dbf file. The indexing expression is in no way related to the
conditional expression that determines whether or not the record will be
represented in the index. In other words, the condition that determines
the presence or absence of a key does not depend upon the value of the
key. For example, a subindex may be created using the expression
"upper(custname)" as the key. The conditional expression could be
"(left(vxcountry,6)="CANADA") .or. (left(vxcountry,6)="U.S.A.". This
would produce an index that represented customers in North America only.
An open subindex in an index list attached to a database is maintained
just as like other index. When a record is added, an index key for the
record is only added if the conditional expression evaluates as TRUE.
If a record is updated, and the update data invalidates the record
for inclusion in the subindex, the key is deleted.
If you regularly filter data based upon a condition such as the one
above, a permanent subindex makes data retrieval MUCH faster. If the
file is large, and you need to set a temporary filter that may result
in very long record retrieval times, it is probably faster to create
a temporary subindex instead. A subindex makes it APPEAR that the database
contains only records that satisfy the conditional logical expression.
COMPATIBILITY ISSUES
--------------------
With release 3.0X, vxBase breaks away from strict xBase standards. Bitmaps
of course may only be retrieved and displayed using vxBase functions.
The header block of a subindex also differs from a standard Clipper NTX
index header block. New elements have been added that define whether or
not the index is a subindex and an area is used to hold the conditional
expression as well.
Release 5.2 of CA-Clipper changes the index header as well and also changes
the index locking scheme. vxBase NTX indexes ARE NOT COMPATIBLE with Clipper
5.2 indexes. Indexes created and/or maintained with any version of Clipper
will NOT properly maintain a vxBase subindex.
Bitmaps and subindexes are specialty items requested by a great many vxBase
users. If compatibility is an issue with your application, it would be best
not to use these functions (although bitmaps may be safely ignored; if the
memo text returns "BIT*MAP" then it may be ignored in a Clipper application).
vxCtlBrowseMsg
--------------
A new message type has been created to extract the current contents of the
user entered quick key value. Define the message in your global module as
Global Const VXB_QUICKDISPLAY = 12
A quick key entry will normally result in a the record pointer being
moved so the KeyCode middle button down event generated by vxCtlBrowse
whenever a new record is highlighted may be used to conveniently ask
for the current quick value. The new message may be used to display
the current quick value in a text box as follows:
Sub BrowseBox_KeyDown (KeyCode As Integer, Shift As Integer)
' Debug.Print KeyCode
If KeyCode = 4 Then
QWinLong& = vxCtlHwnd(QuickBox)
' Note: vxCtlHwnd normally returns an integer but you
' must explicitly cast its value as a long integer
' in order to fulfill the vxCtlBrowseMsg parameter
' requirements
k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_QUICKDISPLAY, ByVal QWinLong&)
End If
End Sub
Note: A VB label MAY NOT BE USED to display the quick value because a
label is a "graphical object" and therefore does not have a window
handle.
NEW FUNCTIONS
-------------
vxBlobRead
----------
Declaration:
HANDLE FAR PASCAL vxBlobRead (memofieldname)
char* memofieldname; /* name of memo field holding blob */
Purpose:
Read a binary large object (blob) from a memo file that was stored with
vxBlobWrite.
Parameters:
memofieldname is either a string variable or a literal string that
contains a valid memo field name from the currently selected database.
MemoFieldName may be qualified with a valid alias name that points to
any open database.
Returns:
A HANDLE to global memory allocated by vxBase. The memory contains
the blob. It is the programmer's responsibility to release the memory
with GlobalFree when he is done with it.
Usage:
Any binary object may be stored in a memo field with vxBlobWrite and
a HANDLE to that object may be extracted with vxBlobRead. The vxPicture
functions are limited to standard BMPs and variants thereof.
Example:
/* ********************************************* */
/* DrawBlob uses a GIF library to place an */
/* image into the window passed to the function */
/* The blob is retrieved from the memo fieldname */
/* stored in the current record */
/* ********************************************* */
BOOL DrawBlob(HWND hwnd, char *fieldname)
{
HANDLE hPicBuffer; // mem handle to blob
LPSTR lpPicBuffer; // string addr of blob
// get the handle to the blob
// if NULL, return FALSE
// ---------------------------
hPicBuffer = vxBlobRead(fieldname);
if (!hPicBuffer)
return(FALSE);
// convert the handle to a string address
// --------------------------------------
lpPicBuffer = GlobalLock(hPicBuffer);
// Draw the image
// --------------
if (!GifConverter(hwnd, lpPicBuffer))
{
GlobalUnlock(hPicBuffer);
GlobalFree(hPicBuffer);
return(FALSE);
}
// release the memory
// ------------------
GlobalUnlock(hPicBuffer);
GlobalFree(hPicBuffer);
return(TRUE);
}
See Also:
vxBlobWrite, vxIsPicture, vxPictureImport, vxPictureRead, vxMemoClear
vxBlobWrite
-----------
Declaration:
int FAR PASCAL vxBlobWrite (hGlobal, memofieldname)
HANDLE hGlobal; // global handle to mem storing blob
char* memofieldname; // name of memo field to put it in
Purpose:
Write a binary large object (blob) into a memo file.
Parameters:
hGlobal is a handle to a global memory object that stores a
binary large object.
MemoFieldName is either a string variable or a literal string that
contains a valid memo field name from the currently selected database.
MemoFieldName may be qualified with a valid alias name that points to
any open database.
Returns:
TRUE if the operation was successful and FALSE if not.
Usage:
Any binary object may be stored in a memo field with vxBlobWrite and
a HANDLE to that object may be extracted with vxBlobRead. The vxPicture
functions are limited to standard BMPs and variants thereof.
vxBase does not free the global memory after writing the blob. That
is the programmer's responsibility.
Example:
/* ********************************************** */
/* GetBlob stores a GIF image into a memo field */
/* The blob is retrieved from the filename passed */
/* to this function */
/* ********************************************** */
BOOL GetBlob(char *filename, char *fieldname)
{
int hFile; // dos file handle
DWORD dwLength; // import file length
HANDLE hPicBuffer; // mem handle to blob
LPSTR lpPicBuffer; // string addr of blob
// verify existence of import file
// --------------------------------
hFile = myFileOpen(filename, 0);
if (hFile < 0) // if error, return FALSE
return(FALSE);
// if zero length, set error
// -------------------------
dwLength = myFileLength(hFile);
if (!dwLength)
return(FALSE);
// if unable to allocate memory, set error
// ---------------------------------------
if (NULL == (hPicBuffer = GlobalAlloc(GHND, (DWORD)dwLength)))
{
_lclose(hFile);
return(FALSE);
}
// read image
// ----------
lpPicBuffer = GlobalLock(hPicBuffer);
_hread(hFile, lpPicBuffer, (DWORD) dwLength); // huge read
_lclose(hFile);
// write image to memo file
// ------------------------
GlobalUnlock(hPicBuffer);
if (!vxBlobWrite(hPicBuffer, fieldname))
{
GlobalFree(hPicBuffer);
return(FALSE);
}
GlobalFree(hPicBuffer);
return(TRUE);
}
See Also:
vxBlobRead, vxIsPicture, vxPictureImport, vxPictureRead, vxMemoClear
vxCreateSubNtx
--------------
Declaration:
Declare Function vxCreateSubNtx Lib "vxbase.dll" (ByVal NewNtxName
As String, ByVal NtxExpr As String, ByVal ForCond As String) As Integer
Purpose:
Create a permanent subindex that represents a defined subset of
records in the main dbf file. Only records that pass the test of
the defined conditional logical expression are included in the index.
Parameters:
NewNtxName is the name of the new index file that is created. The
parameter may be a literal string or a string variable. It may include
a complete path name. If an extension is not specified, vxBase defaults
it to ".ntx". An existing file with the same name is overwritten. File
names must begin with a letter. The file name length is limited by DOS
to 8 characters.
NtxExpr is a valid xBase expression (which may be as simple as a
field name) that is passed as either a literal string or as a string
variable. Maximum length of the expression is 255 characters.
ForCond is a valid xBase expression that evaluates as a logical
TRUE or FALSE. The index built by vxCreateSubNtx is composed of
keys built from records that satisfy the ForCond expression. The ForCond
expression may be passed as either a literal string or as a string
variable. Maximum length of the expression is 255 characters.
Usage:
A subindex is an index that represents a defined subset of records in the
main dbf file. The indexing expression is in no way related to the
conditional expression that determines whether or not the record will be
represented in the index. In other words, the condition that determines
the presence or absence of a key does not depend upon the value of the
key. For example, a subindex may be created using the expression
"upper(custname)" as the key. The conditional expression could be
"(left(vxcountry,6)="CANADA") .or. (left(vxcountry,6)="U.S.A.". This
would produce an index that represented customers in North America only.
An open subindex in an index list attached to a database is maintained
just as like other index. When a record is added, an index key for the
record is only added if the conditional expression evaluates as TRUE.
If a record is updated, and the update data invalidates the record
for inclusion in the subindex, the key is deleted.
If you regularly filter data based upon a condition such as the one
above, a permanent subindex makes data retrieval MUCH faster. If the
file is large, and you need to set a temporary filter that may result
in very long record retrieval times, it is probably faster to create
a temporary subindex instead. A subindex makes it APPEAR that the database
contains only records that satisfy the conditional logical expression.
Warning:
If you are editing a file that is being controlled by a subindex (i.e.,
the index currently selected), field changes or additions that result in
the for condition returning FALSE will leave the record pointer in an
undefined state after the record is saved. If the record is an update,
the key will be removed from the index. If the record is an addition,
the key will not be added to the index. IT IS YOUR RESPONSIBILTY to
position the record pointer to a valid record if this should occur.
There are a number of ways this can be accomplished. If you know
the condition, you can test if the new data will qualify the record
for inclusion in the index. Or you may simply seek for the record again
after writing. If it does not exist, you can position the record
pointer to someplace you have prepared to go to before you began the
update routine. This is the strategy used below:
Example (Updating a subindexed file safely):
--------------------------------------------
' Validate data when save button is pressed
' -----------------------------------------
Sub CustSave_Click ()
' verify something in the field
' -----------------------------
j% = vxSelectDbf(vxClientDbf)
SeekKey$ = CustCode.Text
If EmptyString(SeekKey$) Then
MsgBox "vxSer Field cannot be empty"
Exit Sub
End If
' reread the record
' -----------------
j% = vxSeek(SeekKey$)
ThisRec& = vxRecNo()
' now get previous record in case
' in a subindex situation the changes
' the user makes removes this record
' from the index.
' The subindex condition here is
' vxCountry = 'CANADA' .or. vxCountry = 'U.S.A.'
' If the user has changed the country to
' something else, this record will disappear
' from the index when it is written so we
' must plan on what to do of this happens.
' ----------------------------------------------
j% = vxSkip(-1)
If vxBof() Then
j% = vxTop()
End If
PrevRec& = vxRecNo()
' put record pointer back to update
' ---------------------------------
j% = vxGo(ThisRec&)
' Data passed. Put it away
' ------------------------
j% = vxLockRecord()
Call vxReplString("vxcompany", (CustCompany.Text))
Call vxReplString("vxname", (CustName.Text))
Call vxReplString("vxaddress1", (CustAddress.Text))
Call vxReplString("vxaddress2", (CustAddress2.Text))
Call vxReplString("vxcity", (CustCity.Text))
Call vxReplString("vxstate", (CustState.Text))
Call vxReplString("vxcountry", (CustCountry.Text))
Call vxReplString("vxzip", (CustZip.Text))
Call vxReplString("vxphone", (CustPhBus.Text))
Call vxReplString("vxfax", (CustFax.Text))
j% = vxWrite()
j% = vxWriteHdr()
j% = vxUnlock()
' Update status box
' -----------------
VXFORM1.StatBar.Text = "Record " + LTrim$(Str$(ThisRec&)) + " saved"
' Now see if the record still exists in this index.
' If it doesnt exist, the country has been changed
' so we will go to the Previous record we saved
' above and load the form data with that. Otherwise,
' this record data will remain on the form.
' -------------------------------------------------
If Not vxSeek(SeekKey$) Then
j% = vxGo(PrevRec&)
CustDataLoad
End If
CustReturn = BROWSE_EDIT
RecChange = False
End Sub
Example (Creating a subindex):
' we open a subindex just as we do a normal index
' UserFname$ contains the path and name of the subindex
If Not vxFile(UserFname$) Then
vxCl1Ntx = vxCreateSubNtx(UserFname$, "vxser", "left(vxcountry,6)='CANADA'
.or. left(vxcountry,6)='U.S.A.'")
Else
vxCl1Ntx = vxUseNtx(UserFname$)
End If
See Also:
vxCreateNtx, vxIsSubNtx, vxNtxSubExpr, vxNumRecsSub, vxUseNtx
vxIsPicture
-----------
Declaration:
Declare Function vxIsPicture Lib "vxbase.dll" (ByVal MemoFieldName
As String) As Integer
Purpose:
Determine whether a bitmap is attached to the defined memo field.
Parameters:
MemoFieldName is either a string variable or a literal string that
contains a valid memo field name from the currently selected database.
MemoFieldName may be qualified with a valid alias name that points to
any open database.
Returns:
TRUE if a bitmap is present and FALSE if not. Note that text attached
to the field instead of a bitmap will return FALSE.
Usage:
Could be used to determine whether or not to load a new bitmap.
Example:
' the name of the bmp picture file is the
' same as the string in field "title" so
' we can import the bmps into the memo file
' by cocatenating ".bmp" to the trimmed field
' contents
' -------------------------------------------
j% = vxTop()
If Not vxIsPicture("pic") Then
For i& = 1 To 13 ' there are 13 recs in the file
j% = vxGo(i&)
ftitle$ = vxFieldTrim("type")
fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
If Not vxPictureImport(fname$, "pic") Then
MsgBox "Import Failed"
End If
Next i&
j% = vxClose() ' close ensures buffers flushed
AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
j% = vxSelectDbf(AirPicsDbf)
End If
See Also:
vxIsMemo, vxMemoClear, vxPictureImport, vxPictureRead, vxSetAlias
vxIsSubNtx
----------
Declaration:
Declare Function vxIsSubIndex Lib "vxbase.dll" (ByVal NtxArea As Integer)
As Integer
Purpose:
Determine whether or not the defined index is a subindex or a normal
index.
Parameters:
NtxArea is the select area of an index file returned by vxUseNtx or
vxAreaNtx.
Returns:
TRUE if the index is a subindex or FALSE if it is not.
Usage:
It may be necessary to determine an update strategy or perhaps
do something based upon the record count depending on whether or not the
entire file is represented in the index.
Example:
If vxIsSubNtx(vxNtxCurrent()) Then
NumRecs& = vxNumRecsSub()
Else
NumRecs& = vxNumRecs()
End If
See Also:
vxCreateSubNtx, vxNtxCurrent, vxNtxSubExpr, vxNumRecsSub, vxUseNtx
vxLockRetry
-----------
Declaration:
Declare Sub vxLockRetry Lib "vxbase.dll" (ByVal ErrorMode As Integer,
ByVal WaitSeconds As Integer)
Purpose:
Set the method of reporting a locked file or record to the user and
also specify a lock try timeout value.
Parameters:
ErrorMode is passed as either TRUE or FALSE.
If TRUE (the default), and an operation is performed that requires
a lock (either record or file) which is unable to be set because another
user has control of the record or file, the user is presented with a message
from vxBase that asks if he wishes to retry the operation or abort. If
"Retry" is chosen, vxBase attempts to set the lock again.
If ErrorMode is passed as FALSE, vxBase issues error code 610 "File lock
error" instead of the retry message IF vxSetErrorMethod is set to TRUE. If the
alternate error method is TRUE, the programmer can then set up his own
method of dealing with locks through the VB ON ERROR routine.
If vxSetErrorMethod is FALSE and ErrorMode is FALSE, the default user retry
message is sent instead.
WaitSeconds is the number of seconds to continue to attempt setting a lock.
If zero (0), and a lock fails, the lock function returns with the error
immediately and either presents the "Retry" message to the user or triggers
the vxBase 600 error depending on the value of ErrorMode and vxSetErrorMethod.
If WaitSeconds is greater than zero, vxBase will continue to attempt to set
the lock until WaitSeconds has expired. The maximum number of WaitSeconds that
can be specified is 32,767 (which equates to over 9 hours) and is essentially
a "wait forever" state.
Returns:
Nothing.
Usage:
In a multiuser environment the programmer often wishes to handle the failed
lock scenario himself rather than rely on the user to retry the lock or not. This
is the function of the errormode parameter.
Setting WaitSeconds to about 20 is a good value for normal database operations.
For example, if a record is to be written, vxBase will try over and over again
for 20 seconds to set the lock. After the time has expired, the selected error
method is executed.
If using vxBase in an unattended program, it makes good sense to set the timeout
value very high. Other processes that take control of a file for 15 or 20 minutes
then do not necessarily disrupt the unattended program from performing its tasks
after the file has been released.
NOTE: If a file is opened for exclusive use with vxUseDbfEX then ALL other
processes requiring that file across the entire network will be denied access to
the file. The vxUseDbfEX function sets a network SHARE flag rather than a
Clipper style lock on the file and no one is granted access to the file no matter
what the value of vxSetLocks.
NOTE: vxLockRetry settings are GLOBAL to all vxBase tasks on a workstation.
Once you select a set of values, you should use the same values in all of your vxBase
programs.
Example:
' this function attempts to write a record and, if the required
' lock fails, it send the user its own message asking for a
' another attempt instead of using the vxBase default Retry? message
' ------------------------------------------------------------------
Sub RecWrite
Dim vxError As vxErrorStruc
Dim RetryVal As Integer
vxSetLocks FALSE
vxSetErrorMethod TRUE
vxLockRetry 0, 20
' will use alternate error method after
' retrying a lock for 20 seconds
On Error GoTo LockError
' we will attempt to lock the record
' as long as RetryVal is zero. If the
' lock required by vxWrite fails, we
' exit to the On Error routine - which
' will set RetryVal to 2 if the user
' does not wish to retry.
' -------------------------------------
RetryVal = 0
Do
If vxLockRecord() Then RetryVal = 1
Loop While RetryVal = 0
If RetryVal = 1 Then
If Not vxWrite() Then
MsgBox "Record Write Error"
End If
End If
vxSetErrorMethod FALSE
Exit Sub
LockError:
If vxErrorTest(vxError) Then
If vxError.ErrorNum = 600 Then
j% = MsgBox("Lock failed. Retry?", 52)
If j% = 6 Then
Resume Next
Else
RetryVal = 2
Resume Next
End If
End If
End If
End Sub
See Also:
vxIsRecLocked, vxLockDbf, vxLocked, vxLockRecord, vxSetLocks,
vxUnlock, vxUseDbfEX
vxMemCompact
------------
Declaration:
Declare Function vxMemCompact Lib "vxbase.dll" () As Long
Purpose
Windows memory can become extremely fragmented when running a vxBase
application. The vxBase program architecture is built of many small
chunks which are all discardable and may be loaded on call. Other tasks
running concurrently with vxBase can also contribute to memory
fragmentation and consequent loss of perfromance or even out of memory
conditions when a large request is made for some fixed memory (e.g.,
reading a memo). vxMemCompact uses Windows API routines to compact
memory and leave the largest contiguous free areas possible.
Parameters
None.
Returns
A long integer that contains the number of bytes in the largest free
global memory object in the global heap.
Example
' compact memory on each return to the controlling form
' -----------------------------------------------------
Sub Form_Unload (Cancel As Integer)
vxWindowDereg(VXFORM5.hWnd)
vxMemCompact
End Sub
vxMemoClear
-----------
Declaration:
Declare Function vxMemoClear Lib "vxbase.dll" (ByVal MemoFieldName
As String) As Integer
Purpose:
Remove a memo block reference from a memo field. The bitmap OR memo
attached to the field is effectively deleted.
Parameters:
MemoFieldName is either a string variable or a literal string that
contains a valid memo field name from the currently selected database.
MemoFieldName may be qualified with a valid alias name that points to
any open database.
Returns:
TRUE if the operation was successful and FALSE if not. Always
returns FALSE is always returned if the associated dbf has been opened
as Read Only with vxUseDbfRO.
Usage:
Delete a memo or bitmap.
Example:
Sub ButtonDelete_Click ()
If vxMemoClear("pic") Then
PicBox.Picture = LoadPicture()
Else
MsgBox "Delete failed"
End If
See Also:
vxIsMemo, vxIsPicture, vxReplMemo, vxPictureImport, vxSetAlias
vxMemoPos
---------
Declaration:
Declare Sub vxMemoPos Lib "vxbase.dll" (ByVal StartX As Integer,
ByVal StartY As Integer, ByVal xWidth As Integer, ByVal yHeight As Integer,
ByVal MemoTitle As String)
Purpose:
Set the start position and size of an upcoming memo edit window that
will edit a memo attached to the current database with vxMemoEdit. Also
used to set up the memo edit window title.
Parameters:
Window coordinates passed to this function use familiar character units
in the x dimension and line height units in the y dimension. The units are
converted to the average character width and height of the standard
Windows system font and are therefore device independent.
StartX is the start position of the memo window in characters from the
left edge of the screen.
StartY is the start position of the memo window in lines from the top
of the screen.
xWidth is the start width of the memo window in characters.
yHeight is the height of the memo window (including caption and menu
bars) in lines.
Returns:
Nothing.
Usage:
Memo window position and size are defaulted according to the size of
the parent window passed to the vxMemoEdit function if this command is
not issued. If this Sub is called, the position and size are relative to the
entire screen.
The default memo window caption is "Memo Edit: DBF name". If this is good
enough, pass the MemoTitle as a null value (ByVal 0&).
If you wish to set the memo title only and leave the size and position as
the default values, pass all x and y coordinates as 0. For example,
Call vxMemoPos(0,0,0,0,"My Memo Title")
If the user sizes the memo window according to his own tastes, its position
and size will be retained on subsequent edits.
Example:
Call vxMemoPos(10, 5, 60, 15, "Customer Complaints")
RecNum& = vxRecNo()
Call vxMemoEdit(VXFORM3.hWnd, "a_memo")
j% = vxGo(RecNum&)
j% = vxUnLock()
See Also:
vxMemoEdit
vxMemRealloc
------------
Declaration
Declare Function vxMemRealloc Lib "vxbase.dll" (ByVal NumDbf As Integer,
ByVal NumNtx As Integer, ByVal ReindexBuff As Integer) As Integer
Purpose
Decrease the initial vxBase memory requirements.
Parameters
NumDbf is the number of dbf files that will be opened simultaneously. The
minimum number is 2.
NumNtx is the number of ntx files that will be opened simultaneously. The
minimum number is 2.
ReindexBuff is passed as either TRUE or FALSE. If TRUE, a 64k buffer used
to speed up creation of indexes and the reindex/pack routines is set up. If
this parameter is passed as FALSE, the buffer is either removed (if is has
already been created) or not set up at all.
Returns
TRUE if the memory reallocation was successful and FALSE if not.
Usage
The first call to vxBase allocates about 160,000 bytes to track open dbf
files and open index files and also creates a 64k buffer used by vxReindex,
vxPack, and vxCreateNtx. By calling vxMemRealloc(2, 2, FALSE) this huge block
of memory may be reduced to about 35,000 bytes. If you are not going to
be creating indexes, reindexing, or packing, the ReindexBuff may be passed
as FALSE to remove an immediate 64k.
You should not use this function to INCREASE memory requirements. Let
vxBase handle that automatically. DBF descriptor blocks and NTX buffers
are each limited to 64k (FAR pointer arithmetic is used by vxBase) so the
maximum number of open dbf and ntx files for ALL concurrent vxBase tasks is
about 75. If more memory is required by vxBase, it will increase the size of
each dbf or ntx object by the immediate amount required (to a maximum of
64k each).
This function should be called in your initialization routine. It should
only be called ONCE. It is not designed as an all purpose vxBase memory
manager; rather it is designed to let users with low memory situations
customize specific vxBase applications.
WARNING: Use this function with care. This function CLOSES all open dbf
and ntx files that belong to the current task before the memory is
reallocated. If any files are open that belong to OTHER vxBase tasks,
the function fails. ALWAYS test the result for a TRUE value to ensure
the reallocation takes place.
Example
' The FIRST form load is used to initalize vxbase
' -----------------------------------------------
Sub Form_Load ()
vxInit
vxCtlGraySet
vxSetLocks FALSE
j% = vxCloseAll()
If Not vxMemRealloc(2, 2, FALSE) Then
MsgBox "Reallocation failed"
End
End If
End Sub
See Also
vxInit, vxMemCompact
vxNtxSubExpr
------------
Declaration:
Declare Function vxNtxSubExpr Lib "vxbase.dll" (ByVal NtxArea As Integer)
As String
Purpose:
Extract the conditional expression that controls the insertion/deletion
of keys in a subindex.
Parameters:
NtxArea is the select area of an index file returned by vxUseNtx or
vxAreaNtx.
Returns:
A string that contains the conditional expression used to create the
subindex. The string is either in Visual Basic format or C format depending
upon the value of vxSetString.
Usage:
Especially useful in creating files at run time that are copies of
existing files and that are to be indexed in the same way. Or in reporting
the conditions of index insertion to the user.
Example:
If vxIsSubNtx(vxNtxCurrent()) Then
NumRecs& = vxNumRecsSub()
Form1.Caption = "Subindex on " + vxNtxExpr(vxNtxCurrent()) +
" For Condition " + vxNtxSubExpr(vxNtxCurrent())
Else
NumRecs& = vxNumRecs()
Form1.Caption = "Master Index on " + vxNtxExpr(vxNtxCurrent())
End If
See Also:
vxCreateSubNtx, vxIsSubNtx, vxNtxCurrent, vxNtxExpr, vxNtxSubExpr,
vxNumRecsSub
vxNumRecsFilter
---------------
Declaration:
Declare Function vxNumRecsFilter Lib "vxbase.dll" () As Long
Purpose:
Return the number of records in the database that pass the defined
filter.
Parameters:
None. The number of records returned is for the currently
selected database.
Usage:
Useful for generating accurate scroll bar extents and as a FOR LOOP
counter. Note that this function does exactly what you would do to
determine the number of records in a database that satisfy some
condition. It must read every record in the database, evaluate the
filter, and increment a counter. It is done at a lower level but
still can take a lot of time in a large database.
Example:
j% = vxSelectDbf(TestDbf")
Debug.Print vxNumRecs()
Call vxFilter("trim(vxcountry)='CANADA')
Debug.Print vxNumrecsFilter()
See Also:
vxFilter, vxFilterReset, vxNumRecs, vxNumrecsSub
vxNumRecsSub
------------
Declaration:
Declare Function vxNumRecsSub Lib "vxbase.dll" () As Long
Purpose:
Return the number of records in a subindex.
Parameters:
None. The subindex MUST be the currently selected index.
Usage:
Generally used as a FOR LOOP counter or as a statistic. It may also
be used to set an accurate vertical scroll bar extent.
Example:
If vxIsSubNtx(vxNtxCurrent()) Then
NumRecs& = vxNumRecsSub()
Form1.Caption = "Subindex on " + vxNtxExpr(vxNtxCurrent()) +
" For Condition " + vxNtxSubExpr(vxNtxCurrent())
Else
NumRecs& = vxNumRecs()
Form1.Caption = "Master Index on " + vxNtxExpr(vxNtxCurrent())
End If
See Also:
vxCreateSubNtx, vxIsSubNtx, vxNtxCurrent, vxNtxExpr, vxNtxSubExpr
vxPictureImport
---------------
Declaration:
Declare Function vxPictureImport Lib "vxbase.dll" (ByVal BmpFileName As
String, ByVal MemoFieldName As String) As Integer
Purpose:
Import a bitmap from a system .BMP file into a memo field. The image
may be displayed with vxPictureRead. The maximum size of the bitmap is
16 megabytes.
Parameters:
BmpFileName is the complete name of the bitmap file including path
and extension. Files other than bitmaps may be stored into the memo
file but they may not be read with vxPictureRead (unless they are run
length encoded compressed variants of BMPS - i.e., RLE files in either
4 or 8 bit per pixel format). The file name may be represented by a
literal string or a string variable.
MemoFieldName is either a string variable or a literal string that
contains a valid memo field name from the currently selected database.
MemoFieldName may be qualified with a valid alias name that points to
any open database.
Returns:
FALSE if the function fails and TRUE if successful. FALSE is always
returned if the associated dbf has been opened as Read Only with
vxUseDbfRO.
Usage:
It is much more efficient both from a retrieval standpoint and from
a disk management standpoint to store bitmaps you wish to have
associated with database records in a single source file.
Store pictures of people in personnel files, parts images in
inventory files, homes in real estate files, etc.
Files other than BMPs may also be stored in a memo file. Note, however,
that only BMP or RLE format files are converted by vxPictureRead for display
in a Visual basic picture box. The memo link parameters included in the
vxCtlBrowse function will also result in bitmap display WITHOUT any
effort required by the programmer other that defining the memo window
and memo field name to the vxCtlBrowse function.
Collecting Bitmaps
vxBase takes advantage of the rich body of functions included in Visual
Basic to handle bitmap files. Bitmaps are the Windows norm; all paint
programs, viewers, etc. can handle bitmaps - and most programs that
deal with pictures can convert foreign formats (e.g., GIF) to BMPs.
As a last resort, cut a picture into the clipboard and paste it into a
Windows PAINT window. It can then be stored as a .BMP file.
Once an image is stored in a BMP file it can be transferred to the
memo file with the vxPictureImport function. To retrieve the bitmap,
vxBase uses the standard Windows Clipboard. It puts the bitmap out to
the clipboard as a DIB (device independent bitmap). The Visual Basic
Clipboard.GetData(8) function then is used to retrieve the image
from the clipboard and display it in a VB Picture Box. The box
can have the AUTORESIZE property set to TRUE as in the sample
application if the images are all different sizes
Bitmap files can be created from existing images you may be using in
a Visual Basic program by calling the SavePicture function. You can then
call vxPictureImport to store the image in a memo file by using the name
of the bitmap file you created with SavePicture. You can also SavePicture
to export pictures from a memo file by first reading them into a picture
box with vxPictureRead.
Example:
' the name of the bmp picture file is the
' same as the string in field "title" so
' we can import the bmps into the memo file
' by cocatenating ".bmp" to the trimmed field
' contents
' -------------------------------------------
j% = vxTop()
If Not vxIsPicture("pic") Then
For i& = 1 To 13 ' there are 13 recs in the file
j% = vxGo(i&)
ftitle$ = vxFieldTrim("type")
fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
If Not vxPictureImport(fname$, "pic") Then
MsgBox "Import Failed"
End If
Next i&
j% = vxClose() ' close ensures buffers flushed
AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
j% = vxSelectDbf(AirPicsDbf)
End If
See Also:
vxIsPicture, vxMemoClear, vxPictureRead
vxPictureRead
-------------
Declaration:
Declare Function vxPictureRead Lib "vxbase.dll" (ByVal PicHwnd
As Integer, ByVal MemoFieldName As String) As Integer
Purpose:
Display a bitmap in a defined window that was stored in a memo
file with vxPictureImport.
Parameters:
PicHwnd is the window handle of the window that will receive the
image. In Visual basic, use vxCtlHwnd to convert a control handle to
a window handle.
MemoFieldName is either a string variable or a literal string that
contains a valid memo field name from the currently selected database.
MemoFieldName may be qualified with a valid alias name that points to
any open database.
Returns:
TRUE if the operation was successful and FALSE is not.
Usage:
Only BITMAPS that have been stored with vxPictureImport may be
extracted with vxPictureRead. vxPictureRead assumes the binary object
contained in the memo is a formatted bitmap which contains a Windows
BITMAPFILEHEADER followed by a BITMAPINFOHEADER followed by an array
of RGBQUAD structures. All of this information is then followed by the
bitmap data itself. vxPictureRead creates a DIB (device independent
bitmap) out of the Windows data structures and passes the DIB to the
clipboard, where it can easily be extracted and placed into a Visual
Basic picture box (or onto a form) with the ClipBoard.GetData(8)
function.
If the structure contained in the memo is not a formal bitmap,
who knows what result?
If you wish to store Binary Large Objects (BLOBs) in the memo file
other than bitmaps, you must use the vxBlobWrite and vxBlobRead functions
to access the data. These functions use Windows Global memory handles
as parameters and are not easily available to the Visual Basic programmer.
NOTE: The memo link parameters included in the vxCtlBrowse function
will also result in bitmap display WITHOUT any effort required by the
programmer other than defining the memo window and memo field name to
the vxCtlBrowse function. When vxCtlBrowse displays a bitmap, it auto-
matically sizes the memo link window to the size of the bitmap. The top left
corner of your memo window is anchored. If there is not enough room on the
form to contain the entire bitmap, it is clipped on the right and/or the
bottom to the limits of the parent form.
Example:
The following code is a complete reproduction of the code contained
in VYFORM2 in the vxbtest project sample application:
' static switch set to TRUE in form
' load procedure so we know when this
' form is first loaded
Dim FirstTime As Integer
Sub BrowseBox_KeyDown (KeyCode As Integer, Shift As Integer)
' whenever a record is highlighted, this
' proc receives a middle button code
' from the ctlBrowse so we can dynamically
' display the picture in the memo field
' -------------------------------------------
If KeyCode = 4 Then ' middle button?
j% = vxSelectDbf(AirPicsDbf)
RecNum& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETCURRENTREC, 0)
j% = vxGo(RecNum&)
VYFORM2.Caption = vxFieldTrim("Title")
If vxPictureRead(vxCtlHwnd(PicBox), "pic") Then
' the "8" param below is CF_DIB
PicBox.Picture = Clipboard.GetData(8)
' If you want to leave the picture in
' the clipboard, comment out line below
Clipboard.Clear
Else
PicBox.Picture = LoadPicture() ' clears the picture area
End If
End If
' -----------------------------------------------------------------
' NOTE: the code above is an example of using vxPictureRead.
' In this case (displaying records in a vxCtlBrowse table),
' it would be much more efficient to define the memo window
' and the memo field name to the vxCtlBrowse function instead
' -----------------------------------------------------------------
End Sub
Sub BrowseBox_KeyPress (KeyAscii As Integer)
' NOTE: YOU MUST ALWAYS TRAP THE ENTER KEY
' AND CHANGE THE KEYASCII CODE TO
' A ZERO WHEN USING VXCTLBROWSE
' EVEN IF YOU DON'T USE IT
' ----------------------------------------
If KeyAscii = 13 Then
KeyAscii = 0
Exit Sub
End If
' if ESC key is received, then emulate
' exit button press
' ------------------------------------
If KeyAscii = 27 Then
KeyAscii = 0
ButtonExit_Click
Exit Sub
End If
End Sub
Sub ButtonExit_Click ()
Unload VYFORM2
End Sub
Sub Form_Load ()
' set FirstTime switch on for Paint
' ---------------------------------
FirstTime = True
' register the default database as the master
' -------------------------------------------
AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
j% = vxSelectDbf(AirPicsDbf)
' first time load pictures
j% = vxTop()
' the name of the bmp picture file is the
' same as the string in field "title" so
' we can import the bmps into the memo file
' by cocatenating ".bmp" to the trimmed field
' contents
' -------------------------------------------
If Not vxIsPicture("pic") Then
For i& = 1 To 13
j% = vxGo(i&)
ftitle$ = vxFieldTrim("type")
fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
If Not vxPictureImport(fname$, "pic") Then
MsgBox "Import Failed"
End If
Next i&
j% = vxClose()
AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
j% = vxSelectDbf(AirPicsDbf)
End If
' set up the browse
' -----------------
Call vxTableDeclare(VX_RED, ByVal 0&, ByVal 0&, 0, 1, 1)
Call vxTableField(1, "Type", "type", VX_FIELD)
Call vxBrowseCase(VX_UPPER)
Call vxBrowseSetup(0, 0, 0, 1, "Helv", 15, VX_SEMIBOLD, 0, 0, 0, 0)
' If the typeface is too large on your display,
' CHANGE the parameter following "Helv" above to
' a smaller number
' ----------------------------------------------
' change the mouse pointer in the browse box
' from an I-Beam to an arrow to stop any flicker
' ----------------------------------------------
BrowseBox.MousePointer = 1
End Sub
Sub Form_Paint ()
' register the database with this window
' --------------------------------------
j% = vxSelectDbf(AirPicsDbf)
' make the form 3-d
' -----------------
Call vxFormFrame(VYFORM2.hWnd)
Call vxCtlStyle(BrowseBox, VX_RECESS)
' initiate the browse the first time only
' ---------------------------------------
If FirstTime = True Then
j% = vxCtlBrowse(vxCtlHwnd(BrowseBox), AirPicsDbf, 0, 0, 0, 0, " ")
FirstTime = False
End If
' on initial paint of the browse, middle button
' keydown is not sent to browse box so we want
' to do our dynamic display here as well as
' from a keydown in the browse box code
' ---------------------------------------------
Call BrowseBox_KeyDown(4, 0)
End Sub
Sub Form_Resize ()
VYFORM2.Refresh
End Sub
Sub Form_Unload (Cancel As Integer)
' close the browse
' ----------------
k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_CLOSE, 0)
' close all the files
' -------------------
j% = vxCloseAll()
' deregister the window and release memory
' ----------------------------------------
vxWindowDereg (VYFORM2.hWnd)
End Sub
See Also:
vxIsPicture, vxPictureImport
vxSetSelect
-----------
Declaration
Declare Sub vxSetSelect Lib "vxbase.dll" (ByVal OnOrOff As Integer)
Purpose
Turn off vxBase automatic database selection. Whenever a vxBase
database function is called, the last database selected for the current
window is used to perform the database function. If there was no
database active for the current window, then the last selected database
for the current task is automatically selected instead.
Parameters
If OnOrOff is TRUE (the default), automatic database selection
according to the active window takes place whenever a vxBase function
that accesses a database is called. If FALSE, the last selection is used
without regard to window or task.
Returns
Nothing.
Usage
Used within Visual Basic sub functions where code attached to a
particular form does not come into play. Turning the auto select off
ensures there will be no incorrect selection going on that the
programmer is not aware of. Care must be taken when using this function
because, if the programmer allows the user to open a number of windows
each accessing a different database, the selection process may become
totally unhinged.
vxSetSelect(FALSE) is normally used by C programmers writing DLLs or
VBXs which use vxBase calls. In a DLL, there is commonly no window that
can act as controller and even if there were, the programmer knows
exactly what database he is using and can reselect at every opportunity
to ensure the correct data comes into play.
Example
' sub function that does not interfere
' with auto selection of database in
' main line
' ------------------------------------
Sub GetMasterNum()
Call vxSetSelect(FALSE)
PrevDbf% = vxSelectDbf(MasterDbf)
MasterNum = vxInteger("masternum")
Call vxSetSelect(TRUE)
j% = vxSelectDbf(PrevDbf%)
End Sub
See Also
vxSelectDbf
vxUseDbfAgain
-------------
Declaration:
Declare Function vxUseDbfAgain lib "vxbase.dll" (ByVal DbfName
As String) As Integer
Purpose:
Opens a database that has already been opened IN ANOTHER AREA.
Any indexes attached to this database with vxUseNtx are also opened
in areas separate from any other instances of the same files.
See Also:
vxUseDbf
vxUseDbfEX
----------
Declare Function vxUseDbfEX lib "vxbase.dll" (ByVal DbfName
As String) As Integer
Purpose:
Opens a database for EXCLUSIVE use. If any other user or
task is currently using the database, this function will
fail (zero is returned as the select area).
See Also:
vxUseDbf
IMPORTANT NOTES TO EXISTING VXBASE USERS:
-----------------------------------------
(1) If your application uses DESCENDing indexs and your current vxBase
release is less than 2.08, these indexes MUST BE RECREATED after
installing this release. The descending key algorithm has been
changed to make vxBase descending keys compatible with CLIPPER
descending keys.
DO NOT USE DATAWORKS to recreate the indexes. It still uses the
old algorithm. DataWorks is in the process of update.
Use the vxReindex or vxCreateNtx functions to recreate the indexes.
(2) See the VXLOAD.EXE discussion below.
Prerequisites
-------------
vxBase is a dynamic link library of xBase functions that has been
customized for use with Microsoft Visual Basic. You must have
Visual Basic in order to run the VB sample application.
If you are intending to use vxBase with another language (such as
C), create the directory \VB before beginning installation of vxBase.
The default installation directory is \VB, which is where
Visual Basic is normally set up. The directory that vxBase is
installed into MUST exist. If \VB does not exist, or if you wish
to install vxBase into another directory, ensure that it exists
prior to installation.
vxBase Installation
-------------------
If INSTALL.EXE is resident on this diskette, use the
program manager RUN command A:INSTALL to install
vxBase. If changing the default directory from \VB,
the directory being changed to MUST exist.
A second sample application (project vxbtut) has been
included starting with release 2.05 that shows you how
to maintain a single database using vxCtlBrowse as the
primary user interface to the database. It is installed
in directory \vb\vxbtest along with the vxbtest project.
ZIP version
-----------
vxBase is distributed on a single diskette or on bulletin boards
as two compressed .ZIP files. The first ZIP file is vxbdoc.zip, which
contains the documentation in a Windows Write file. This file is
essential to understanding and using vxBase. If it is missing, contact
the author at the address below. The documentation is separated from
the rest of vxBase to allow potential users to preview it before
installing and actually using vxBase. This is especially helpful to
potential users who extract vxBase from a bulletin board. They can
evaluate the system from a documentation standpoint before committing to
downloading the larger system.
Unzip vxbdoc.zip and view or print it. The manual is more than
250 pages long. It was formatted for an Epson 24-pin printer using
standard Courier fonts. Printed manuals may be obtained for $20.00.
See the end of the documentation for ordering information.
The second ZIP file (vxbase.zip) contains the sample source code
and Visual Basic project files, vxbase.txt which includes all of the Visual
Basic declarations for the routines in the vxBase DLL, the vxBase DLL
itself, and VXLOAD.EXE - a Visual Basic Design Mode Utility.
If you are going to upload vxBase to a bulletin board, it must be
sent as it was received - in two ZIP files.
When the system ZIP file is decompressed, it contains this readme.doc
file and 3 more ZIP files. These ZIP files are:
vxbdll.zip the vxBase DLL and vxload.exe
vxbtest.zip sample source code and vxbase.txt
vxbezy.zip single database sample app using vxCtlBrowse
(project vxbtut)
To install vxBase, first make a subdirectory under your \vb
directory named \vb\vxbtest and copy the vxbtest.zip and vxbezy.zip files
there. Unzip them and delete the zip files from your hard disk. To run the
sample applications it is essential that these files be in directory \vb\vxbtest
because this path is hard-coded into the sample code. If you MUST put them
somewhere else, you'll have to modify the file names in the source code to
reflect your location.
Unzip vxbdll.zip and place the resulting files (VXBASE.DLL and VXLOAD.EXE)
in your \windows directory.
To run the sample program, see the Sample Application section in the
manual. Remember to run vxload.exe before starting Visual Basic.
VISUAL BASIC 2.0 And the Sample Applications
--------------------------------------------
Visual Basic 2.0 or better is REQUIRED to run the sample
applications.
Better Memory Management in Design Mode with VXLOAD.EXE
-------------------------------------------------------
NOTE: vxload.exe included with vxbase is a utility that simply
loads vxbase.dll and runs in an iconized state. It is
highly recommended that you run this program immediately
PRIOR to calling up Visual Basic in Design Mode. vxload
controls the vxbase memory. Any crashes when testing a vxbase
program in design mode will not affect the vxbase memory pool
at all if vxload is running. Copy vxload.exe to your \windows
directory and set it up as a group item next to your VB icon.
It is also suggested that you add the following two lines of
code to your initialization procedure (somewhere after the call
to vxInit()):
Call vxSetLocks(FALSE)
j% = vxCloseAll()
vxSetLocks is described in the namual.
Adding these two lines to the init procedure will close any
files that were left open as a result of a Design Mode VB
error. vxSetLocks will ensure that any open files left over
from a crashed VB run will not have any leftover locks on
your second and subsequent runs of the program while in Design
Mode - and vxCloseAll will close any leftover files so you can
start off with a clean slate.
If you wish to use the default locking scheme in your finished
.EXE, remove the vxSetLocks(FALSE) that you set up for design mode
testing before compiling (and the vxCloseAll as well although
that is not critical).
If your vxBase program terminates abnormally (or you use the VB End
menu item to terminate), and then you exit Visual Basic, an
attempt to close VXLOAD.EXE from the system menu that appears
when you click on its icon will result in a "Task Sequence Closure
Error". This is because your vxBase Visual Basic program never
called vxDeallocate, which removes Visual Basic from the vxBase
task list being maintained by VXLOAD. If this happens to you,
simply double click the VXLOAD icon to bring the VXLOAD window
into view and select the EXIT menu item. Closing VXLOAD in this
fashion ignores the task list.
Changes to vxBase version 2.xx
------------------------------
(1) vxBrowseSetup corrected to display user menus if system menus
disabled.
(2) vxCtlStyle corrected to handle new Visual Basic 2.0 "graphical
objects" (e.g., labels).
(3) all SETTINGS cited as System Wide in the current documentation are
now local to the vxBase task. These settings include the following:
vxCtlPenWidth
vxSetAnsi
vxSetCollate/vxCollate collating table
vxSetDate
vxSetErrorCaption
vxSetErrorMethod
vxSetLanguage
vxSetLocks
vxSetMeters
vxSetString
If more than one vxBase task is running at the same time, the
items set by the functions above are now local to each concurrent
task (e.g., vxBase in French and in English can be run on the same
machine at the same time).
(4) inconsistent index file lockup in multiuser mode when vxSeek
fails corrected.
(5) DESCEND and vxDescend index algorithms changed to use 2s complement
instead of 1s complement arithmetic to convert defined descending
keys into the correct sequence. This makes the vxBase DESCEND
index compatible with CLIPPER.
(9) memo soft returns from Clipper apps are now properly stripped on
European memos when vxSetAnsi is FALSE.
(10) vxBrowse and vxCtlBrowse quick key displays and vertical scrolling
speeds have been increased by a factor of 2 to 3.
(11) memory leaks created by VB 2.0 string creation corrected by using
new function to create Visual Basic strings if version is 2.0 or
greater.
(12) Max memo size now increased to 64k (was 32k).
(13) memo reading procedures changed to read 4k blocks instead of 64k file
chunks. This should speed memo reads and packs with memo files
considerably.
(14) vxAppendFrom now appends memos and bitmaps. Restriction removed.
(15) vxGo() passed with a zero record number now returns FALSE instead
of crashing.
(16) vxTop now properly returns FALSE if empty file.
(17) dbf files opened as Read Only with vxUseDbfRO no longer have their
index files locked when positioning to a specific record.
(18) more elegant on screen edit within a vxBrowse or vxCtlBrowse table.
The use may accept the edit by pressing the ENTER key or cancel the
edit by pressing ESC.
(19) initial memory allocation requirements reduced and memory increase
requests changed to leave new memory object attached to original
calling task.
(20) Dutch language support added.
Terry Orletsky
vxBase Systems
#488, 9707 - 110 Street
Edmonton, Alberta, Canada
T5K 2L9
Phone (403) 488-8100
Fax (403) 486-8150
BBS (403) 488-8365 up to 14400 bps v.32bis 8N1
Compuserve I.D. 70524,3723